import React, { useEffect, useRef, useState, useMemo } from "react";
import { connect } from "react-redux";
import { Swiper, Image, DotLoading, SpinLoading } from "antd-mobile";
import { Skeleton } from "antd-mobile";
import {
  queryNewsLatest,
  queryNewsBefore,
  getUserInfo,
} from "./../../service/api";
import "./index.less";
import action from "./../../store/actions/index";

// 在JSX里面想使用图片，导入在使用。不能直接在img写相对路径。 CSS里面的图被处理过
// let img = require('@/assets/favicon.png')
import img from "@/assets/timg.jpg";

const monthMap = {
  "01": "一月",
  "02": "二月",
  "03": "三月",
  "04": "四月",
  "05": "五月",
  "06": "六月",
  "07": "七月",
  "08": "八月",
  "09": "九月",
  10: "十月",
  11: "十一月",
  12: "十二月",
};

/* 20241227 字符串转年月日数组  */
const dayFormat = (dataString) => {
  return dataString.match(/^(\d{4})(\d{2})(\d{2})$/).slice(1);
};

/* 月日不足2位，补0 */
const setZero = (val) => {
  val = String(val);
  return val.length >= 2 ? val : `0${val}`;
};

const Home = (props) => {
  console.log("home-component-render ...");
  const { navigate, userInfo, setUserInfo } = props;

  /* 头像  */
  const avatarImg = useMemo(() => {
    return userInfo?.pic ? userInfo.pic : img;
  }, [userInfo]);

  /* 创建所需要的状态 */
  let [today, setToday] = useState(() => {
    const year = new Date().getFullYear();
    const date = setZero(new Date().getDate());
    const month = setZero(new Date().getMonth() + 1);
    return dayFormat(`${year}${date}${month}`);
  });
  let [bannerData, setBannerData] = useState([]);
  let [newsList, setNewsList] = useState([]);
  let loadMoreRef = useRef(null);

  /* 跳转到详情页面 */
  const handlerDetail = (id) => {
    props.navigate(`/details/${id}`);
  };

  /* 绑定banner信息 */
  const bindBannerData = async () => {
    try {
      let { top_stories, date } = await queryNewsLatest();
      setBannerData(top_stories);
      setToday(dayFormat(date));
      bindNewsList(date);
    } catch (error) {
      console.log("获取最新新闻失败 ...", error);
    }
  };

  /* 绑定新闻列表信息 */
  const bindNewsList = async (dayDate) => {
    try {
      let { stories, date } = await queryNewsBefore(dayDate);
      let storiesMap = stories.map((item) => {
        item.date = date;
        return item;
      });
      setNewsList(storiesMap);
    } catch (error) {
      console.log("获取以往新闻失败 ...", error);
    }
  };

  /* 上滑加载更多 */
  const bindMoreLoadData = () => {
    console.log("componentDidMount");
    let obj = new IntersectionObserver(async (change) => {
      let { isIntersecting } = change[0];
      console.log(newsList);
      if (isIntersecting) {
        let time = newsList.length && newsList[newsList.length - 1].date;
        let { stories, date } = await queryNewsBefore(time);
        let storiesMap = stories.map((item) => {
          item.date = date;
          return item;
        });
        // state发生改变后 ->  组件先卸载componentWillUnmount -> 再次刷新组件componentDidMount
        setNewsList([...newsList, ...storiesMap]);
      }
    });

    let loadMoreBox = loadMoreRef.current;
    obj.observe(loadMoreBox);

    // 组件释放时候执行
    return () => {
      console.log("componentWillUnmount");
      obj.unobserve(loadMoreBox);
      obj = null;
    };
  };

  /* 获取用户信息 */
  const getLoginUserInfo = async () => {
    const { code, data } = await getUserInfo();
    if (code === 0) {
      window.localStorage.setItem("useInfo", JSON.stringify(data));
      setUserInfo(data);
    }
  };

  /* 组件第一次渲染完毕后：从服务器获取数据 */
  useEffect(() => {
    getLoginUserInfo();
    bindBannerData();
  }, []);

  /* 页面状态发生改变后，触发函数执行 componentDidMount & componentDidUpdate,不是很好 */
  useEffect(() => {
    return bindMoreLoadData();
  });

  return (
    <div className="home-page">
      <div className="header-view">
        <div className="info">
          <p>
            <span>{today[2]}</span>
            <span>{monthMap[today[1]]}</span>
          </p>
          <h2 className="title">早点休息</h2>
        </div>
        <div
          className="avatar-view"
          onClick={() => {
            const token = window.localStorage.getItem("tk");
            token ? navigate("/personal") : navigate("/login?to=personal");
          }}
        >
          <img src={avatarImg} />
        </div>
      </div>

      <div className="banner-view">
        {bannerData.length > 0 ? (
          <Swiper autoplay={true} loop={true}>
            {bannerData.map((item) => {
              return (
                <Swiper.Item key={item.id}>
                  <div
                    className="banner-item"
                    onClick={handlerDetail.bind(null, item.id)}
                  >
                    <Image src={item.image} alt="" lazy />
                    <div className="banner-cont">
                      <h2>{item.title}</h2>
                      <p className="author-info">
                        <span>{item.hint}</span>
                      </p>
                    </div>
                  </div>
                </Swiper.Item>
              );
            })}
          </Swiper>
        ) : (
          <SpinLoading color="primary" />
        )}
      </div>
      <div className="content-view">
        {newsList.length > 0 ? (
          <>
            {newsList.map((item) => {
              return (
                <div
                  className="item-view"
                  key={item.id}
                  onClick={handlerDetail.bind(null, item.id)}
                >
                  <div className="content-list-cont">
                    <h3>{item.title}</h3>
                    <p>{item.hint}</p>
                  </div>
                  <div className="content-list-img">
                    <Image src={item.images[0]} alt="" lazy />
                  </div>
                </div>
              );
            })}
            <div></div>
          </>
        ) : (
          <SpinLoading color="primary" />
        )}
        <div
          className="loadMore-view"
          ref={loadMoreRef}
          style={{ display: newsList.length > 0 ? "block" : "none" }}
        >
          <DotLoading />
          <span>加载中</span>
        </div>
      </div>
    </div>
  );
};

export default connect((state) => state.baseReducer, action.baseAction)(Home);
